package com.example.devinfan.criminalintent.Fragment;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import com.example.devinfan.criminalintent.R;
import com.example.devinfan.criminalintent.model.Photo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

public class CrimeCameraFragment extends Fragment {
    private static final String TAG = "CrimeCameraFragment";

    public static final String EXTRA_PHOTO = "com.example.devinfan.criminalintent.photo";
    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private View mProgressContainer;
    private Camera.Parameters mParameters;
    private Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback(){
        @Override
        public void onShutter(){
            //Display the progress indicator
            mProgressContainer.setVisibility(View.VISIBLE);
        }
    };
    private Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            //Create a filename
            String filename = UUID.randomUUID().toString()+".jpg";
            //save the jpeg data the disk
            FileOutputStream os = null;
            boolean success = true;
            try{
                os = getActivity().openFileOutput(filename, Context.MODE_PRIVATE);
                os.write(data);
            }catch (Exception e){
                Log.e(TAG,"Error writing to file"+filename,e);
                success = false;
            }finally {
                try{
                    if(os != null){
                        os.close();
                    }
                }catch (Exception e){
                    Log.e(TAG,"Error closing file "+filename,e);
                    success = false;
                }
            }
            //Set the photo filename on the result intent
            if(success){
                Log.i(TAG,"JPEG save at "+filename);
                Photo photo = new Photo(filename);
                Intent intent = new Intent();
                intent.putExtra(EXTRA_PHOTO,photo);
                getActivity().setResult(Activity.RESULT_OK,intent);
            }else{
                getActivity().setResult(Activity.RESULT_CANCELED);
            }
            getActivity().finish();
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent,Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.fragment_crime_camera,parent,false);

        mProgressContainer = view.findViewById(R.id.crime_camera_progressContainer);
        mProgressContainer.setVisibility(View.INVISIBLE);

        Button tackPictureButton = (Button) view.findViewById(R.id.crime_camera_takePictureButton);
        tackPictureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCamera != null){
                    mCamera.setParameters(mParameters);
                    mCamera.takePicture(mShutterCallback,null,mJpegCallback);
                }
            }
        });

        OrientationEventListener mOrientationEventListener = new OrientationEventListener(getActivity(), SensorManager.SENSOR_DELAY_NORMAL) {
            @Override
            public void onOrientationChanged(int orientation) {
                if(orientation == ORIENTATION_UNKNOWN) return ;
                Camera.CameraInfo info = new Camera.CameraInfo();
                Camera.getCameraInfo(0,info);
                orientation = (orientation + 45) / 90 * 90;
                int rotation;
                if(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
                    rotation = (info.orientation - orientation + 360) % 360;
                }else{
                    rotation = (info.orientation + orientation) % 360;
                }
                mParameters.setRotation(rotation);
            }
        };
        mOrientationEventListener.enable();

        mSurfaceView = (SurfaceView) view.findViewById(R.id.crime_camera_surfaceView);
        SurfaceHolder holder = mSurfaceView.getHolder();
        //setType() and SURFACE_TYPE_PUSH_BUFFERS are both deprecated
        //but are required for Camera preview to work on pre-3.0 devices.
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                //tell the camera to use this surface as its preview area
                try{
                    if(mCamera != null){
                        mCamera.setPreviewDisplay(holder);
                    }
                }catch (IOException e){
                    Log.e(TAG, "Error setting up preview display",e);
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if (mCamera == null) return ;
                Log.i(TAG,"changed");
                //the surface has changed size; update the camera preview size
                Camera.Size s = getBestSupportedSize(mParameters.getSupportedPictureSizes(),width,height);
                mParameters.setPictureSize(s.width,s.height);
                mCamera.setParameters(mParameters);
                try{
                    mCamera.startPreview();
                }catch (Exception e){
                    Log.e(TAG,"Could not start preview",e);
                    mCamera.release();
                    mCamera = null;
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                //we can no longer display on this surface , so stop the preview
                if (mCamera != null){
                    mCamera.stopPreview();
                }
            }
        });

        return view;
    }

    @Override
    public void onResume(){
        super.onResume();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD){
            mCamera = Camera.open(0);
            mParameters = mCamera.getParameters();
        }else{
            mCamera = Camera.open();
            mParameters = mCamera.getParameters();
        }
    }


    @Override
    public void onPause(){
        super.onPause();

        if(mCamera != null){
            mCamera.release();
            mCamera = null;
        }
    }

    //不是怎么好的取最适合分辨率方法
    private Camera.Size getBestSupportedSize(List<Camera.Size> sizes,int width,int height){
        Camera.Size bestSize = sizes.get(0);
        int largestArea = bestSize.width * bestSize.height;
        for(Camera.Size s : sizes){
            int area = s.width * s.height;
            if(area > largestArea){
                bestSize = s;
                largestArea = area;
            }
        }
        return bestSize;
    }

}
